#include <QtGui/QtGui>
#include <QtCore/QtCore>

#include "OgreWidget.h"

OgreWidget::OgreWidget(QWidget *parent)
    : QWidget(parent), stopRendering(false), root(0), renderWindow(0)
{
    QGridLayout *gridLayout = new QGridLayout(parent);
    gridLayout->setSpacing(0);
    gridLayout->setContentsMargins(0, 0, 0, 0);
    gridLayout->addWidget(this, 0, 0, 1, 1);

	setAttribute(Qt::WA_PaintOnScreen);
	setAttribute(Qt::WA_NoSystemBackground);

	setFocusPolicy(Qt::StrongFocus);

    SetupOgre();
}

OgreWidget::~OgreWidget()
{

}

void OgreWidget::SetupOgre()
{
    root = Ogre::Root::getSingletonPtr();

    if (!root) {
        return;
    }

    Ogre::NameValuePairList params;
	params["useNVPerfHUD"] = "true";

    // *nix requires a different method to get the window handle - this works for MSWindows
    // Mac requires additional params
    params["externalWindowHandle"] = Ogre::StringConverter::toString((size_t)(winId()));

    renderWindow = root->createRenderWindow("RenderWindow", width(), height(), false, &params);

    root->getRenderSystem()->addListener(this);
    root->addFrameListener(this);
    
    renderWindow->windowMovedOrResized();
        
    sceneManager = root->createSceneManager("OctreeSceneManager", "Scene");
    sceneManager->setAmbientLight(Ogre::ColourValue(0.7f, 0.7f, 0.7f));
    sceneManager->setAmbientLight(Ogre::ColourValue(0.05f, 0.05f, 0.05f));

    camera = sceneManager->createCamera("Camera");
    camera->setPosition(Vector3(0, 0, 100));
    camera->lookAt(Vector3(0, 0, -500));
    camera->setNearClipDistance(5);

    viewport = renderWindow->addViewport(camera);
    
    TextureManager::getSingleton().setDefaultNumMipmaps(5);
}

void OgreWidget::UpdateOgre()
{
    if(renderWindow) {
		root->_fireFrameStarted();
		renderWindow->update();
		root->_fireFrameRenderingQueued();
		root->_fireFrameEnded();
    }
}

void OgreWidget::eventOccurred (const Ogre::String &eventName, const Ogre::NameValuePairList *parameters)
{
    if (screenResized) return;
    if (eventName == "DeviceLost") stopRendering = true;
}

QPaintEngine *OgreWidget::paintEngine() const
{
    // disable the Qt painting engine
    return 0;
}

void OgreWidget::paintEvent(QPaintEvent *evt)
{
    UpdateOgre();
}
    
void OgreWidget::resizeEvent(QResizeEvent *evt)
{
    if(!renderWindow)
        return;

    screenResized = true;

    renderWindow->windowMovedOrResized();
    camera->setAspectRatio(Real(width()) / Real(height()));

    evt->accept();

    screenResized = false;
}